package android.cmw.comw.refreshlistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * Created by Administrator on 2017-05-03.
 * 作用：自定义下拉刷新的ListView
 */

public class RefreshListView extends ListView {

    LinearLayout headerView;
    /**
     * 顶部轮播图视图
     */
    View topBannerView;
    private View ll_pull_down_refresh;
    private ImageView iv_arrow;
    private ProgressBar pb_status;
    private TextView tv_status;
    private TextView tv_time;
    /**
     * 刷新 ll_pull_down_refresh 高度
     */
    private int pull_down_refresh_height = -1;


    /**
     * 下拉刷新
     */
    private static final int PULL_DOWN_REFRESH = 0;
    /**
     * 手松刷新
     */
    private static final int RELEASE_REFRESH = 1;
    /**
     * 正在刷新
     */
    private static final int REFRESHING = 2;
    /**
     * 当前状态
     */
    private int currentStatus = PULL_DOWN_REFRESH;

    private Animation upAnimation;
    private Animation downAnimation;
    /**
     * 底部加载更多...
     */
    private View footerView;
    /**
     * 底部加载更多控件高度
     */
    private int footerViewHeight;
    private boolean isLoadMore = false;
    /**
     * ListView 在屏幕中的Y坐标值
     */
    private int listViewOnScreenY = -1;

    public RefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initHeaderView(context);
        initAnimation();
        initFooterView(context);
    }

    private void initFooterView(Context context){
        footerView = View.inflate(context, R.layout.refresh_footer, null);
        footerView.measure(0,0);
        footerViewHeight = footerView.getMeasuredHeight();
        footerView.setPadding(0,-footerViewHeight,0,0);
        addFooterView(footerView);
        setOnScrollListener(new MyOnScrollListener());
    }

    int lastItem = 0;

    /**
     * 加载顶部轮播图
     * @param topBannerView    顶部轮播图视图
     */
    public void addTopBannersView(View topBannerView) {
        if(null == topBannerView) return;
        this.topBannerView = topBannerView;
        headerView.addView(topBannerView);
    }

    /**
     * 滚动事件
     */
    public class MyOnScrollListener implements OnScrollListener{

        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {
            //当静止或惯性滚动时候
            if(i == SCROLL_STATE_IDLE || i == SCROLL_STATE_FLING){
                //并且最后一条可见时
                if(getLastVisiblePosition() >= getCount()-1){
                    //1.显示底部加载更多控件
                    footerView.setPadding(8,8,8,8);//显示底部加载更多控件
                    //2.状态改变
                    isLoadMore = true;
                    //3.加载数据
                    if(null != mOnRefreshListener){
                        mOnRefreshListener.onLoadMore();
                        //底部加载更多后，让其默认停留在最后一条（解决加载完数据后，自动返回顶部的问题）
                        setSelection(lastItem-1);
                    }

                }
            }
        }

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            lastItem = firstVisibleItem + visibleItemCount;
        }
    }



    /**
     * 初始化下拉刷新的动画（箭头动画）
     */
    private void initAnimation() {
        upAnimation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        upAnimation.setDuration(500);//动画时间：半秒
        upAnimation.setFillAfter(true);//停留在播放后的状态

        downAnimation = new RotateAnimation(-180, -360,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        downAnimation.setDuration(500);//动画时间：半秒
        downAnimation.setFillAfter(true);//停留在播放后的状态
    }


    private void initHeaderView(Context context) {
        headerView = (LinearLayout)View.inflate(context, R.layout.refresh_header, null);
        ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh);
        iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
        pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
        tv_status = (TextView) headerView.findViewById(R.id.tv_status);
        tv_time = (TextView) headerView.findViewById(R.id.tv_time);

        /*
         *   测量下拉刷新控件
         *   view.measure(int,int)用于询问(或称为设置)当前view需要(想要)占用多大得空间。
         *  简单理解为，为view申请两个int值大小的尺寸的控件
        */
        ll_pull_down_refresh.measure(0,0);
        pull_down_refresh_height = ll_pull_down_refresh.getMeasuredHeight();
        ll_pull_down_refresh.setPadding(0,-pull_down_refresh_height,0,0);
        addHeaderView(headerView);
    }

    private float startY = -1;
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN :{
                //当按下时记录起始坐标
                startY = ev.getY();
                break;
            }case MotionEvent.ACTION_MOVE :{
                makeRefresh(ev);
                break;
            }case MotionEvent.ACTION_UP :{
                startY = -1;
                if(currentStatus == PULL_DOWN_REFRESH){//下拉刷新隐藏
                    ll_pull_down_refresh.setPadding(0, -pull_down_refresh_height, 0, 0);
                }else if(currentStatus == RELEASE_REFRESH){//手松刷新
                    currentStatus = REFRESHING;
                    ll_pull_down_refresh.setPadding(0, 0, 0, 0);
                    refreshStateView();
                }
                break;
            }
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 处理下拉刷新的显示、隐藏及数据加载
     * @param ev
     */
    private void makeRefresh(MotionEvent ev) {
        if(startY == -1){
            startY = ev.getY();
        }
        //记录移动后的新的坐标
        float endY = ev.getY();
        //计算滑动的距离
        float distanceY = endY - startY;
        if(distanceY > 0){
            //判断顶部轮播图片是否完全显示，只有完全显示时才会有下拉刷新（解决在底部加载完数据后，向上滑动时，直接触发下拉刷新的问题）
            boolean isDisplayTopBanners = isDisplayTopBanners();
            if(!isDisplayTopBanners) return;

            if(currentStatus == REFRESHING){
                return;
            }
            int top = (int)(-pull_down_refresh_height + distanceY);
            ll_pull_down_refresh.setPadding(0,top,0,0);
            if(top < 0 && currentStatus != PULL_DOWN_REFRESH){
                currentStatus = PULL_DOWN_REFRESH;//下拉刷新
            }else if(top > 0 && currentStatus != RELEASE_REFRESH){
                currentStatus = RELEASE_REFRESH;//手松刷新
                //更新视图状态
                refreshStateView();
                //调用下拉刷新事件加载数据
                if(null!= this.mOnRefreshListener){
                    this.mOnRefreshListener.onPullDownRefresh();
                }
            }
        }
    }

    private boolean isDisplayTopBanners() {
        if(null == topBannerView) return true;
        int[] location = new int[2];
        if(-1 == listViewOnScreenY){
            getLocationOnScreen(location);
            listViewOnScreenY = location[1];
        }
        //2.得到轮播图片在屏幕上的Y坐标
        topBannerView.getLocationOnScreen(location);
        int topBannerViewOnScreenY = location[1];
        //3.当滑动到顶部轮播图的Y坐标超出ListView的Y坐标时，返回 true ，可执行下拉刷新
        if(listViewOnScreenY <= topBannerViewOnScreenY){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 刷新视图状态
     */
    private void refreshStateView() {
        switch (currentStatus){
            case PULL_DOWN_REFRESH :{//下拉刷新
                tv_status.setText("下拉刷新...");
                iv_arrow.startAnimation(downAnimation);
                break;
            } case RELEASE_REFRESH :{//手松刷新
                tv_status.setText("手松刷新...");
                iv_arrow.startAnimation(upAnimation);
                break;
            } case REFRESHING :{//正在刷新
                tv_status.setText("正在刷新...");
                pb_status.setVisibility(VISIBLE);
                iv_arrow.setVisibility(GONE);
                iv_arrow.clearAnimation();
                break;
            }
        }
    }

    /**
     * 下拉刷新事件
     */
    private OnRefreshListener mOnRefreshListener;

    /**
     * 设置下拉刷新事件
     * @param listener  下拉刷新对象
     */
    public void setOnRefreshListenr(OnRefreshListener listener){
        this.mOnRefreshListener = listener;
    }

    /**
     * 下拉刷新完成调用
     * @param b boolean 值 [true:下拉刷新加载数据成功，false:加载失败]
     */
    public void onRefreshFinish(boolean b) {
        if(isLoadMore){//底部加载更多... 隐藏
            footerView.setPadding(0, -footerViewHeight, 0, 0);
            isLoadMore = false;
        }else{
            tv_status.setText("下拉刷新...");
            pb_status.setVisibility(GONE);
            currentStatus = PULL_DOWN_REFRESH;
            iv_arrow.clearAnimation();
            iv_arrow.setVisibility(VISIBLE);
            //隐藏下拉刷新控件
            ll_pull_down_refresh.setPadding(0, -pull_down_refresh_height, 0, 0);
            if(b){
                tv_time.setText("上次更新时间："+getDateTime());
            }
        }
    }

    /**
     * 获取一个 年月日 时分秒的日期字符串
     * @return 返回一个 年月日 时分秒的日期字符串
     */
    public static String getDateTime(){
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    /**
     * ListView 下拉刷新监听器
     */
    public interface OnRefreshListener{
        /**
         * 下拉刷新方法
         */
        void onPullDownRefresh();

        /**
         * 底部加载更多调用方法
         */
        void onLoadMore();
    }
}
